package managedbean;

import entity.DepartmentEntity;
import entity.PersonEntity;
import entity.RightEntity;
import entity.RightLinkEntity;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

import entity.RoleEntity;
import entity.SystemUserEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import util.Fixtures.Department;
import util.Utils;

public class AuthorizationFilter extends AbstractBacking implements Filter {

    private String timeoutPage = "/timeout.xhtml";
    FilterConfig config = null;
    ServletContext servletContext = null;
    private static final String TIMEOUT_PAGE = "/timeout.xhtml";
    private static final String LOGIN_PAGE = "/index.xhtml";

    public AuthorizationFilter() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
        servletContext = config.getServletContext();
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        Utils.log(servletContext, "Inside the filter");

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpSession session = httpRequest.getSession();

        String requestPath = httpRequest.getServletPath();
//        System.out.println(requestPath + " requested path");
        FacesMessage msg = null;

        Visit visit = (Visit) session.getAttribute("visit");
//        System.out.println(httpRequest.getPathInfo() + "hhhhhhhh");
        if (visit == null) {
            msg = new FacesMessage(FacesMessage.SEVERITY_WARN, " Error", "Please log in first before proceeding further");
//            System.out.println("rrrrrrrrrrrrr");

            Utils.log(servletContext, "redirecting to " + httpRequest.getContextPath()
                    + LOGIN_PAGE);

            httpResponse.sendRedirect(httpRequest.getContextPath() + LOGIN_PAGE);


        } else {
            PersonEntity user = visit.getUser();

//            boolean in;
//            in = purchasing();
//            if (in) {
//                chain.doFilter(request, response);
//            }
         //   boolean rightFolder = checkLink(user,requestPath);
//         if(rightFolder) chain.doFilter(request, response);
            boolean inright = checkRight(user, requestPath);
            System.out.println(requestPath + " : person has right " + inright);

            if (!inright ) {

                httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);

            } else {
                chain.doFilter(request, response);
               
            }
        }

        Utils.log(servletContext, "Exiting the filter");
    }

    public boolean checkRight(PersonEntity user, String requestPath) {
//        return true;
        boolean hasRight = false;

        HashSet<RightEntity> rights = new HashSet<RightEntity>();
        rights.addAll(user.getRights());
      
        for (RoleEntity role : user.getRoles()) {
            rights.addAll(role.getRights());
        }

        HashSet<RightLinkEntity> links = new HashSet<RightLinkEntity>();
        for (RightEntity right : rights) {
            links.addAll(right.getLinks());
        }

        RightLinkEntity toCheck = new RightLinkEntity();
        toCheck.setRightLink(requestPath);
        if (links.contains(toCheck)) {
            hasRight = true;
        }

       return hasRight;
//        return true;
    }
//
//    public boolean inFolder(String requestPath, PersonEntity user) {
//        List<RightEntity> rights = allUserRights(user);
//
//        for (RightEntity right : rights) {
//
//            if (right.getFolder() != null) {
//
//                String t = right.getFolder().toString();
//
//                if (requestPath.indexOf(t) > 0) {
//
//                    return true;
//                }
//            }
//        }
//        return false;
//    }

    public boolean checkLink(PersonEntity user, String requestPath) {
//        return true;
        boolean hasRight = false;

        List<RightEntity> rights = allUserRights(user);
     

       List<RightLinkEntity> links = new ArrayList<RightLinkEntity>();
        for (RightEntity right : rights) {
              System.out.println(right.getRightName()+"zzzzz");
            links.addAll(right.getLinks());
        }

        RightLinkEntity toCheck = new RightLinkEntity();
        toCheck.setRightLink(requestPath);
        System.out.println(requestPath+"ttt");
        for (RightLinkEntity link : links) {
             System.out.println(link.getRightLink()+"yyyyy");
            if (requestPath.indexOf(link.getRightLink()) > 0) {
                hasRight = true;
            }
        }
        return hasRight;
    }

    public List<RightEntity> allUserRights(PersonEntity user) {
        List<RightEntity> rights = new ArrayList<RightEntity>();
        rights.addAll(user.getRights());
        for (RoleEntity role : user.getRoles()) {
            rights.addAll(role.getRights());
        }
        return rights;
    }

    public boolean checkRole(PersonEntity user, String role) {
//return true;
        boolean inrole = false;
        Collection<RoleEntity> Groups = user.getRoles();
        String[] groups = new String[Groups.size()];
        int i = 0;
        for (RoleEntity rg : Groups) {
            groups[i] = rg.getRoleName();
            FacesContext facesContext = FacesContext.getCurrentInstance();
            Utils.log(servletContext, "User: " + user + " Group: " + rg.getRoleName());



            if (groups[i].equalsIgnoreCase(role)) {
                inrole = true;
                break;
            }
            i++;
        }
        return inrole;
    }

    public void destroy() {
    }
//    public boolean purchasing() {
//        return checkDepartment(Department.Purchasing);
//
//    }
//
//    public boolean checkDepartment(Department d) {
//
//        SystemUserEntity user = (SystemUserEntity) getCurrentUser();
//        DepartmentEntity d1 = user.getDepartment();
//        if (d1.getName().equalsIgnoreCase(d.getName())) {
//            return true;
//        }
//        return false;
//
//
//
//    }
}
